<template>
  <div>
    <input type="text" @input="handleSearch">
  <canvas ref="canvas" :width="mapWidth" :height="mapHeight">对不起，您的浏览器不支持！</canvas>
  </div>
</template>
<script setup>
import {onMounted,onUnmounted,reactive,ref,watch} from 'vue';

const pixelRatio=window.devicePixelRatio
const mapWidth=pixelRatio*800
const mapHeight=pixelRatio*600
const canvas = ref(null)
const cellWidth=100*pixelRatio
const cellHeight=50*pixelRatio
const padding=10*pixelRatio
let startIndex=0;
const visibleIndex=Math.ceil(mapHeight/cellHeight)-1
const selectedIndex=reactive({row:-1,col:-1})

const d={
  columns:[
    {
      key:"name",
      title:"姓名",
      width:100
    },
    {
      key:"age",
      title:"年龄",
      width:100
    }
  ],
  dataSource:Array.from({length:100}).map((item,index)=>({
    key:index,
    name:`name-${index}`,
    age:Math.floor(Math.random()*100)
  }))
}

const data=reactive({
  ...d,
  tmpData:JSON.parse(JSON.stringify(d.dataSource))
})

defineEmits('click')

const handleClick=(ev)=>{
  const {left,top}=canvas.value.getBoundingClientRect();
  const x=ev.clientX-left
  const y=ev.clientY-top
  const rowIndex=Math.floor(y*pixelRatio/cellHeight)-1+startIndex
  const colIndex=Math.floor(x*pixelRatio/cellWidth)
  if(rowIndex>=0&&rowIndex<data.dataSource.length){
    selectedIndex.row=rowIndex
    selectedIndex.col=colIndex
  }
  drawPic()
}

const randomColor=()=>{
  const random=Math.random()
  if(random>=0&&random<0.3){
    return 'red'
  }else if(random>=0.3&&random<0.6){
    return 'green'
  }else{
    return 'blue'
  }
}

const handleWheel=()=>{
  document.addEventListener('wheel',(ev)=>{
    const {deltaY}=ev
    if(deltaY<0){
      startIndex=Math.max(0,startIndex-1)
    }else{
      startIndex=Math.min(data.dataSource.length-visibleIndex,startIndex+1)
    }
    drawPic()
  })
  
}
const handleSearch=(ev)=>{
  const {value}=ev.target
  console.log("value",value);
  
  data.dataSource=data.tmpData.filter(item=>item.name.includes(value))
}

const drawPic=()=>{
  canvas.value?.addEventListener('click',handleClick)

  const ctx=canvas.value.getContext('2d')
  const {columns,dataSource}=data

  ctx.clearRect(0,0,mapWidth,mapHeight)

  ctx.beginPath()

  // 表头
  for(let i=0;i<columns.length;i++){
    ctx.font=`${pixelRatio*16}px serif`
    ctx.fillText(columns[i].title,i*cellWidth+padding,cellHeight/2)
  }

  for(let i=startIndex;i<startIndex+visibleIndex;i++){
    const record=dataSource[i]
    for(let j=0;j<columns.length;j++){
      const column=columns[j]
      if(i===selectedIndex.row&&j===selectedIndex.col){
        ctx.fillStyle=randomColor()
        ctx.fillRect(j*cellWidth,(i-startIndex+1)*cellHeight,cellWidth,cellHeight)
        ctx.fillStyle='black'
      }
      ctx.fillText(record[column.key],j*cellWidth+padding,(i-startIndex+1)*cellHeight+cellHeight/2)
    }
  }
  
  ctx.closePath()
}


onMounted(()=>{
  drawPic()
  handleWheel()
})

onUnmounted(()=>{
  canvas.value?.removeEventListener('click',handleClick)
})

watch(
  ()=>data.dataSource,
  ()=>drawPic()
)
</script>
<style scoped>
div{
  display: flex;
  flex-direction: column
}
canvas{
  width: 800px;
  height: 600px;
  background-color: #efefef;
}
</style>
